package io.sodabox.server;

import io.sodabox.server.utils.DataUtils;

import java.util.concurrent.ConcurrentMap;

import org.vertx.java.core.Handler;
import org.vertx.java.core.buffer.Buffer;
import org.vertx.java.core.http.HttpServer;
import org.vertx.java.core.json.JsonObject;
import org.vertx.java.core.logging.Logger;
import org.vertx.java.core.sockjs.SockJSServer;
import org.vertx.java.core.sockjs.SockJSSocket;
import org.vertx.java.deploy.Verticle;

public class AppServer extends Verticle {

	private Logger log;

	private ConcurrentMap<String, SockJSSocket> socketStorage;
	
	private String channel;

	@Override
	public void start() throws Exception {

		log = container.getLogger();
		socketStorage = vertx.sharedData().getMap(AppConstants.SOCKET_STORAGE);

		JsonObject appConfig = container.getConfig();

		if(appConfig.size() == 0){
			String configString = loadStaticData(AppConstants.DEFAULT_CONF_FILE);
			appConfig = new JsonObject(configString);
		}

		JsonObject serverConfig = appConfig.getObject("server");
		log.info("RECEIVER SERVER : "+serverConfig);
		
		channel = serverConfig.getString("channel");

		HttpServer server = vertx.createHttpServer();
		SockJSServer sockServer = vertx.createSockJSServer(server);

		sockServer.installApp(
				new JsonObject().putString("prefix", "/receiver"), 
				new Handler<SockJSSocket>() {
					public void handle(final SockJSSocket sock) {

						System.out.println("sock.writeHandlerID : "+sock.writeHandlerID+" / "+SockJSSocket.cnt);

						sock.endHandler(new Handler<Void>(){
							public void handle(Void event) {
								socketStorage.remove(sock.writeHandlerID);
								System.out.println("- endHandler : "+sock.writeHandlerID+" / "+socketStorage.size());

							}
						});

						sock.dataHandler(new Handler<Buffer>() {
							public void handle(Buffer data) {

								if( DataUtils.join(data)){ // Command : JOIN
									socketStorage.put(sock.writeHandlerID, sock);

								}else if( DataUtils.test(data)){ // Command : TEST
									JsonObject jo =  DataUtils.getTestData(data);

									if(socketStorage.containsKey(jo.getString("SOCK_ID"))){
										socketStorage.get(jo.getString("SOCK_ID")).writeBuffer(new Buffer(jo.toString()));
									}

								}else{
									sock.writeBuffer(data);
								}

							}
						});
					}
				});

		server.listen(
				Integer.parseInt(serverConfig.getString("port")), 
				serverConfig.getString("host")
				);

	}

	private String loadStaticData(String filename) {
		if (filename == null || filename.isEmpty()) {
			return null;
		}

		Buffer buffer = null;
		String data = null;

		try {
			buffer = vertx.fileSystem().readFileSync(filename);
			data = buffer.getString(0, buffer.length());
		} catch (Exception e) {
			log.error(e.getMessage());
		}

		return data;
	}

}
